import ctypes
import time
import os
import platform

# 自动选择合适的 SDK 库
if platform.system() == "Windows":
    sdk = ctypes.CDLL("./dll/HCNetSDK.dll")  # Windows 下的 DLL
elif platform.system() == "Linux":
    sdk = ctypes.CDLL("./so/libhcnetsdk.so")  # Linux 下的 SO 库，替换为实际路径
else:
    raise OSError("不支持的操作系统！")

# 定义设备信息结构体
class NET_DVR_DEVICEINFO_V30(ctypes.Structure):
    _fields_ = [
        ("sSerialNumber", ctypes.c_byte * 48),
        ("byAlarmInPortNum", ctypes.c_byte),
        ("byAlarmOutPortNum", ctypes.c_byte),
        ("byDiskNum", ctypes.c_byte),
        ("byDVRType", ctypes.c_byte),
        ("byChanNum", ctypes.c_byte),
        ("byStartChan", ctypes.c_byte),
        ("byAudioChanNum", ctypes.c_byte),
        ("byIPChanNum", ctypes.c_byte),
        ("byZeroChanNum", ctypes.c_byte),
        ("byMainProto", ctypes.c_byte),
        ("bySubProto", ctypes.c_byte),
        ("bySupport", ctypes.c_byte),
        ("bySupport1", ctypes.c_byte),
        ("bySupport2", ctypes.c_byte),
        ("wDevType", ctypes.c_ushort),
        ("bySupport3", ctypes.c_byte),
        ("byMultiStreamProto", ctypes.c_byte),
        ("byStartDChan", ctypes.c_byte),
        ("byStartDTalkChan", ctypes.c_byte),
        ("byHighDChanNum", ctypes.c_byte),
        ("bySupport4", ctypes.c_byte),
        ("byLanguageType", ctypes.c_byte),
        ("byVoiceInChanNum", ctypes.c_byte),
        ("byStartVoiceInChanNo", ctypes.c_byte),
        ("byRes3", ctypes.c_byte * 2),
        ("byMirrorChanNum", ctypes.c_byte),
        ("wStartMirrorChanNo", ctypes.c_ushort),
        ("byRes2", ctypes.c_byte * 2),
    ]

# 定义 JPEG 参数结构体
class NET_DVR_JPEGPARA(ctypes.Structure):
    _fields_ = [
        ("wPicSize", ctypes.c_ushort),  # 图片大小，0 表示自动
        ("wPicQuality", ctypes.c_ushort),  # 图片质量（0-最好，1-较好，2-一般）
    ]

# 初始化SDK
sdk.NET_DVR_Init()

# 设备信息
devices = [
    {"ip": b"192.168.21.64", "username": b"admin", "password": b"sdsd22BMX", "port": 8000},
]

user_ids = []

for dev in devices:
    device_info = NET_DVR_DEVICEINFO_V30()
    user_id = sdk.NET_DVR_Login_V30(dev["ip"], dev["port"], dev["username"], dev["password"], ctypes.byref(device_info))
    if user_id < 0:
        print(f"登录 {dev['ip'].decode()} 失败，错误码:", sdk.NET_DVR_GetLastError())
    else:
        print(f"登录 {dev['ip'].decode()} 成功")
        user_ids.append((user_id, dev["ip"].decode(), device_info.byStartChan))

# 图片保存路径
save_path = "./snapshots/"
if not os.path.exists(save_path):
    os.makedirs(save_path)

# JPEG 图片参数
jpeg_param = NET_DVR_JPEGPARA()
jpeg_param.wPicSize = 0  # 自动选择最佳分辨率
jpeg_param.wPicQuality = 0  # 最高质量

# 每秒抓拍一次
for i in range(10):
    for user_id, ip, start_chan in user_ids:
        chan_num = start_chan  # 设备的起始通道号

        pic_path = os.path.join(save_path, f"{ip}_snap_{i}.jpg")
        pic_buffer = ctypes.create_string_buffer(pic_path.encode("utf-8"))

        # 直接抓拍，不需要实时预览
        if sdk.NET_DVR_CaptureJPEGPicture(user_id, chan_num, ctypes.byref(jpeg_param), pic_buffer):
            print(f"{ip} 抓拍成功: {pic_path}")
        else:
            print(f"{ip} 抓拍失败，错误码:", sdk.NET_DVR_GetLastError())

    time.sleep(1)

# 退出登录并释放资源
for user_id, ip, _ in user_ids:
    sdk.NET_DVR_Logout(user_id)

sdk.NET_DVR_Cleanup()
print("程序结束")
